﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using OPCAutomation;

namespace Bussiness
{
    public class OPClib
    {
        public string OPCAddress = string.Empty;
        public string Address = string.Empty;
        public OPCServer server;
        public string ErrorMsg = "";
        public OPClib(string _OPCAddress, string _Address)
        {
            server = new OPCServer();
            this.OPCAddress = _OPCAddress;
            this.Address = _Address;
        }

        public bool Open()
        {
            try
            {
                server.Connect(OPCAddress, Address);//1连接 6断开
            }
            catch (Exception ex)
            {
                ErrorMsg = ex.ToString();
                return false;
            }
            return true;
        }

        /// <summary>
        /// 获取opc值（缓冲区）
        /// </summary>
        /// <param name="_GroupName"></param>
        /// <param name="_TagName"></param>
        /// <returns></returns>
        public string GetValue(string _GroupName, string _TagName)
        {
            try
            {
                object val = this.CustomGroups.GetGroup(_GroupName).OPCGroup.OPCItems.Item(_TagName).Value;
                if (val != null)
                {
                    return val.ToString();
                }
                else
                {
                    return "";
                }
            }
            catch (Exception ex)
            {
                ErrorMsg = ex.ToString();
                return "";
            }
        }

        /// <summary>
        /// 获取opc值（设备）
        /// </summary>
        /// <param name="_GroupName"></param>
        /// <param name="_TagName"></param>
        /// <returns></returns>
        public string GetDeviceValue(string _GroupName, string _TagName)
        {
            try
            {
                object value, quality, timestamp;
                this.CustomGroups.GetGroup(_GroupName).OPCGroup.OPCItems.Item(_TagName).Read(2, out value, out quality, out timestamp);
                if (value != null)
                {
                    return value.ToString().ToLower();
                }
                else
                {
                    return "";
                }
            }
            catch (Exception ex)
            {
                ErrorMsg = ex.ToString();
                return "";
            }
        }

        /// <summary>
        /// 写opc值（设备）
        /// </summary>
        /// <param name="_GroupName">组名</param>
        /// <param name="_TagName">变量名</param>
        /// <param name="value">要写入的值</param>
        /// <returns></returns>
        public bool SetDeviceValue(string _GroupName, string _TagName, string value)
        {
            try
            {
                this.CustomGroups.GetGroup(_GroupName).OPCGroup.OPCItems.Item(_TagName).Write(value);
                return true;
            }
            catch (Exception ex)
            {
                ErrorMsg = ex.ToString();
                return false;
            }

        }

        /// <summary>
        /// 写opc值（设备）
        /// </summary>
        /// <param name="_GroupName">组名</param>
        /// <param name="_TagHandle">变量句柄</param>
        /// <param name="value">要写入的值</param>
        /// <returns></returns>
        public void SetDeviceValue(string _GroupName, object _TagHandle, string value)
        {
            this.CustomGroups.GetGroup(_GroupName).OPCGroup.OPCItems.Item(_TagHandle).Write(value);
        }

        public void LoadGroup_AutoHandles()
        {
            foreach (CustomGroup g in CustomGroups)
            {
                g.OPCGroup = server.OPCGroups.Add(g.GroupName);
                int idx = 1;
                foreach (Tag t in g.Tags)
                {
                    try
                    {
                        g.OPCGroup.OPCItems.AddItem(t.TagName, idx);
                    }
                    catch (Exception ex)
                    {
                        ErrorMsg = ex.ToString();
                    }
                    idx++;
                }
                // g.OPCGroup.IsActive = true;//激活组
            }
        }
        /// <summary>
        /// 加载组的datachange事件委托
        /// </summary>
        public void DataChangeEventLoad()
        {
            foreach (CustomGroup g in CustomGroups)
            {
                if (g.IsDataChangeEvent)
                {
                    g.EventLoad();
                }
            }
        }
        public void Start_DataChangeEventLoad(bool is_star)
        {
            foreach (CustomGroup g in CustomGroups)
            {
                if (g.IsDataChangeEvent)
                {
                    if (!is_star)
                    {
                        g.OPCGroup.IsActive = false;//激活组
                        g.OPCGroup.IsSubscribed = false;//激活datachange
                    }
                    else
                    {
                        g.OPCGroup.IsActive = true;//激活组
                        g.OPCGroup.IsSubscribed = true;//激活datachange
                    }
                }
            }
        }
        public void LoadGroup()
        {
            foreach (CustomGroup g in CustomGroups)
            {
                g.OPCGroup = server.OPCGroups.Add(g.GroupName);
                foreach (Tag t in g.Tags)
                {
                    g.OPCGroup.OPCItems.AddItem(t.TagName, t.TagHandles);
                }

                if (g.IsDataChangeEvent)
                {
                    g.EventLoad();
                }
            }
        }

        public void ResLoadGroup()
        {
            foreach (CustomGroup g in CustomGroups)
            {
                DelGroup(g.GroupName, g.OPCGroup);
                g.OPCGroup = server.OPCGroups.Add(g.GroupName);

                foreach (Tag t in g.Tags)
                {
                    g.OPCGroup.OPCItems.AddItem(t.TagName, t.TagHandles);
                }

                if (g.IsDataChangeEvent)
                {
                    g.OPCGroup.IsActive = true;//激活组
                    g.OPCGroup.IsSubscribed = true;//激活datachange
                    g.EventLoad();
                }
            }
        }

        public void DelGroup(string _GroupName, OPCGroup op)
        {
            try
            {
                server.OPCGroups.Remove(_GroupName);
                op = null;
            }
            catch (Exception ex)
            {
                ErrorMsg = ex.ToString();
            }
        }

        public void AddItem(string GroupName, string ItemID, int ClientHandle)
        {
            CustomGroup g = this.CustomGroups.GetGroup(GroupName);
            if (g != null)
            {
                this.CustomGroups.GetGroup(GroupName).OPCGroup.OPCItems.AddItem(ItemID, ClientHandle);
            }
        }

        public void Close()
        {
            if (server.ServerState == 1)
            {
                server.Disconnect();
            }
        }
        private GroupCollection _CustomGroups = new GroupCollection();

        public GroupCollection CustomGroups
        {
            get
            {
                return _CustomGroups;
            }
            set
            {
                _CustomGroups = value;
            }
        }

    }

    public class TagCollection : CollectionBase
    {
        public TagCollection()
          : base()
        {

        }
        public Tag Add(string _TagName, int _TagHandles)
        {
            Tag t = GetTag(_TagName);
            if (t != null)
            {
                return t;
            }
            t = new Tag(_TagName, _TagHandles);

            InnerList.Add(t);
            return t;
        }
        public Tag Add(string _TagName)
        {
            Tag t = GetTag(_TagName);
            if (t != null)
            {
                return t;
            }
            t = new Tag(_TagName);
            InnerList.Add(t);
            return t;
        }
        public Tag GetTag(string _TagName)
        {
            foreach (object o in InnerList)
            {
                if (((Tag)o).TagName == _TagName)
                {
                    return (Tag)o;
                }
            }
            return null;
        }
        public Tag GetTag(int _TagHandles)
        {
            foreach (object o in InnerList)
            {
                if (((Tag)o).TagHandles == _TagHandles)
                {
                    return (Tag)o;
                }
            }
            return null;
        }

    }
    public class Tag
    {
        private string _TagName = string.Empty;

        public string TagName
        {
            get
            {
                return _TagName;
            }
            set
            {
                _TagName = value;
            }
        }
        private int _TagHandles;

        public int TagHandles
        {
            get
            {
                return _TagHandles;
            }
            set
            {
                _TagHandles = value;
            }
        }
        public Tag()
        {

        }
        public Tag(string _Tag_Name, int _TagHandles)
        {
            this.TagName = _Tag_Name;
            this.TagHandles = _TagHandles;
        }
        public Tag(string _Tag_Name)
        {
            this.TagName = _Tag_Name;
            this.TagHandles = 0; ;
        }
    }

    public class GroupCollection : CollectionBase
    {
        public GroupCollection()
          : base()
        {

        }
        public CustomGroup Add(string _GroupName)
        {
            CustomGroup g = new CustomGroup(_GroupName);
            InnerList.Add(g);
            return g;
        }
        public CustomGroup Add(string _GroupName, bool _IsDataChangeEvent)
        {
            CustomGroup g = new CustomGroup(_GroupName, _IsDataChangeEvent);
            InnerList.Add(g);
            return g;
        }
        public CustomGroup GetGroup(string _GroupName)
        {
            foreach (object o in InnerList)
            {
                if (((CustomGroup)o).GroupName == _GroupName)
                {
                    return (CustomGroup)o;
                }
            }
            return null;
        }

    }
    public class CustomGroup
    {
        private string _GroupName = string.Empty;

        public string GroupName
        {
            get
            {
                return _GroupName;
            }
            set
            {
                _GroupName = value;
            }
        }

        private bool _IsDataChangeEvent = false;

        public bool IsDataChangeEvent
        {
            get
            {
                return _IsDataChangeEvent;
            }
            set
            {
                _IsDataChangeEvent = value;
            }
        }
        private TagCollection _Tags = new TagCollection();

        public TagCollection Tags
        {
            get
            {
                return _Tags;
            }
            set
            {
                _Tags = value;
            }
        }
        private OPCGroup _OPCGroup;
        public OPCGroup OPCGroup
        {
            get
            {
                return _OPCGroup;
            }
            set
            {
                _OPCGroup = value;
            }
        }
        public CustomGroup()
        {

        }
        public CustomGroup(string _Group_Name, bool _Is_DataChangeEvent)
        {
            this.GroupName = _Group_Name;
            this.IsDataChangeEvent = _Is_DataChangeEvent;
        }
        public CustomGroup(string _Group_Name)
        {
            this.GroupName = _Group_Name;
        }
        public event EventHandler<EventData> DataChange;
        public void EventLoad()
        {
            this.OPCGroup.DataChange += new DIOPCGroupEvent_DataChangeEventHandler(group_DataChange);
        }
        void group_DataChange(int TransactionID, int NumItems, ref Array ClientHandles, ref Array ItemValues, ref Array Qualities, ref Array TimeStamps)
        {
            EventData ed = new EventData();
            ed.GroupName = this.GroupName;
            for (int i = 1; i <= NumItems; i++)
            {
                DataChangeObject dco = new DataChangeObject();
                dco.TagHandler = ClientHandles.GetValue(i).ToString();
                dco.TagFullName = this.OPCGroup.OPCItems.Item(int.Parse(dco.TagHandler)).ItemID;
                dco.TagValue = ItemValues.GetValue(i).ToString();
                dco.Qualitie = Qualities.GetValue(i).ToString();
                dco.TimeStamp = TimeStamps.GetValue(i).ToString();
                ed.ChangeValues.Add(dco);
            }

            if (DataChange != null)
            {
                DataChange(ClientHandles, ed);
            }

        }
    }

    public class EventData : EventArgs
    {
        public EventData()
        {
        }
        private string _GroupName = string.Empty;

        public string GroupName
        {
            get
            {
                return _GroupName;
            }
            set
            {
                _GroupName = value;
            }
        }
        private List<DataChangeObject> _ChangeValues = new List<DataChangeObject>();

        public List<DataChangeObject> ChangeValues
        {
            get
            {
                return _ChangeValues;
            }
            set
            {
                _ChangeValues = value;
            }
        }


    }
    public class DataChangeObject
    {
        private string _TagFullName = string.Empty;

        /// <summary>
        /// 变量名
        /// </summary>
        public string TagFullName
        {
            get
            {
                return _TagFullName;
            }
            set
            {
                _TagFullName = value;
            }
        }
        private string _TagHandler = string.Empty;

        /// <summary>
        /// 变量索引
        /// </summary>
        public string TagHandler
        {
            get
            {
                return _TagHandler;
            }
            set
            {
                _TagHandler = value;
            }
        }
        private string _TagValue = string.Empty;

        /// <summary>
        /// 变量值
        /// </summary>
        public string TagValue
        {
            get
            {
                return _TagValue.ToLower();
            }
            set
            {
                _TagValue = value;
            }
        }
        private string _Qualitie = string.Empty;

        public string Qualitie
        {
            get
            {
                return _Qualitie;
            }
            set
            {
                _Qualitie = value;
            }
        }
        private string _TimeStamp = string.Empty;

        public string TimeStamp
        {
            get
            {
                return _TimeStamp;
            }
            set
            {
                _TimeStamp = value;
            }
        }
    }
}
